 /***********************************************************
 *  File_Name  : XJXMLProfile.cpp
 *  File_Path   : 
 *  File_Encode : UTF8
 *  Description : XML配置文件读写类
 *  
 *  OS : Linux, UNIX
 *  LastVersion  : 20130723
 *      
 *  Author      : LiXiujie(李秀杰)
 *  Date        : 2013-7-23
 *  Version     : 20130723
 *  Description : 
 *                
 *  Edit Author : 
 *  Edit Date   : 
 *  Version     : 
 *  Description :
 *                
 ***********************************************************/

#include "XJXMLProfile.h"
#include "tinyxml.h"

namespace XJUtilClass {

XJXMLProfile::XJXMLProfile() {
	// TODO Auto-generated constructor stub

}
XJXMLProfile::XJXMLProfile(const string &strFilePath){
	ReadFile(strFilePath);
}

XJXMLProfile::~XJXMLProfile() {
	// TODO Auto-generated destructor stub
}

int XJXMLProfile::AddItem(const XJXMLProfileDataItem &item){
	m_strLastError.clear();
	unsigned int i = 0;
	for(i=0;i<m_veDataItems.size();i++){
		if (m_veDataItems[i].GetCate() == item.m_strCate &&
				m_veDataItems[i].GetName() == item.m_strName){
			m_veDataItems[i] = item;
			return 0;
		}
	}
	if (i == m_veDataItems.size())
		m_veDataItems.push_back(item);
	return 0;
}

int XJXMLProfile::SetItem(const XJXMLProfileDataItem &item){
	m_strLastError.clear();
	unsigned int i = 0;
	for(i=0;i<m_veDataItems.size();i++){
		if (m_veDataItems[i].GetCate() == item.m_strCate &&
				m_veDataItems[i].GetName() == item.m_strName){
			m_veDataItems[i] = item;
			return 0;
		}
	}
	if (i == m_veDataItems.size())
		m_veDataItems.push_back(item);
	return 0;
}

int XJXMLProfile::DelItem(const string & strItemName){
	m_strLastError.clear();
	vector<XJXMLProfileDataItem >::iterator it = m_veDataItems.begin();
	while(it != m_veDataItems.end()){
		XJXMLProfileDataItem &item = *it;
		if (item.m_strCate == "Default" && item.m_strName == strItemName){
			it = m_veDataItems.erase(it);
			return 0;
		}
		it++;
	}
	m_strLastError = "Not found!";
	return -1;
}

int XJXMLProfile::DelItem(const string & strCategoryName, const string & strItemName){
	m_strLastError.clear();
	vector<XJXMLProfileDataItem >::iterator it = m_veDataItems.begin();
	while(it != m_veDataItems.end()){
		XJXMLProfileDataItem &item = *it;
		if (item.m_strCate == strCategoryName && item.m_strName == strItemName){
			it = m_veDataItems.erase(it);
			return 0;;
		}
		it++;
	}
	m_strLastError = "Not found!";
	return -1;
}

XJXMLProfileDataItem & XJXMLProfile::GetItem(const string & strItemName){
	m_strLastError.clear();
	m_itemNull = XJXMLProfileDataItem();
	vector<XJXMLProfileDataItem >::iterator it = m_veDataItems.begin();
	while(it != m_veDataItems.end()){
		XJXMLProfileDataItem &item = *it;
		if (item.m_strCate == "Default" && item.m_strName == strItemName){
			return item;
		}
		it++;
	}
	m_strLastError = "Not found!";
	return m_itemNull;
}

XJXMLProfileDataItem & XJXMLProfile::GetItem(const string & strCategoryName, const string & strItemName){
	m_strLastError.clear();
	m_itemNull = XJXMLProfileDataItem();
	vector<XJXMLProfileDataItem >::iterator it = m_veDataItems.begin();
	while(it != m_veDataItems.end()){
		XJXMLProfileDataItem &item = *it;
		if (item.m_strCate == "Default" && item.m_strName == strItemName){
			return item;
		}
		it++;
	}
	m_strLastError = "Not found!";
	return m_itemNull;
}

string &XJXMLProfile::GetItemValue(const string & strItemName){
	m_strLastError.clear();
	m_itemNull = XJXMLProfileDataItem();
	vector<XJXMLProfileDataItem >::iterator it = m_veDataItems.begin();
	while(it != m_veDataItems.end()){
		XJXMLProfileDataItem &item = *it;
		if (item.m_strCate == "Default" && item.m_strName == strItemName){
			return item.m_strValue;
		}
		it++;
	}
	m_strLastError = "Not found!";
	return m_itemNull.m_strValue;
}

string &XJXMLProfile::GetItemValue(const string & strCategoryName, const string & strItemName){
	m_strLastError.clear();
	m_itemNull = XJXMLProfileDataItem();
	vector<XJXMLProfileDataItem >::iterator it = m_veDataItems.begin();
	while(it != m_veDataItems.end()){
		XJXMLProfileDataItem &item = *it;
		if (item.m_strCate == strCategoryName && item.m_strName == strItemName){
			return item.m_strValue;
		}
		it++;
	}
	m_strLastError = "Not found!";
	return m_itemNull.m_strValue;
}

int XJXMLProfile::ReadFile(const string &strFilePath){
	m_strLastError.clear();
	TiXmlDocument doc(strFilePath.c_str());
	if (!doc.LoadFile()){
		m_strLastError = "ReadFile load file error.";
		m_strLastError += strFilePath;
		return -1;
	}
	//doc.Print();
	if (doc.Parse(strFilePath.c_str()) == NULL){
		m_strLastError = "ReadFile parse file error.";
		m_strLastError += strFilePath;
		m_strLastError += doc.ErrorDesc();
		return -1;
	}
	//获得根元素，即configures。
	TiXmlElement *rootElement = doc.RootElement();
	if (NULL == rootElement){
		m_strLastError = "ReadFile get RootElement error.";
		m_strLastError += strFilePath;
		m_strLastError += doc.ErrorDesc();
		return -1;
	}
	TiXmlElement *eleCate = NULL, *eleItem = NULL;
	TiXmlAttribute *attr = NULL;
	m_veDataItems.clear();
	string strCateName;
	for (eleCate = rootElement->FirstChildElement(); eleCate != NULL; eleCate = eleCate->NextSiblingElement()){
		strCateName = "Default";
		if (strcmp(eleCate->Value(), "cate") != 0)
		{
			continue;
		}
		eleItem = eleCate;
		for (attr = eleItem->FirstAttribute();attr != NULL;attr = attr->Next()){
			if (strcmp(attr->Name(), "name") == 0){
				strCateName = attr->Value();
			}
		}
		for (eleItem = eleCate->FirstChildElement(); eleItem != NULL; eleItem = eleItem->NextSiblingElement()){
			if (strcmp(eleItem->Value(), "item") != 0)
			{
				continue;
			}
			XJXMLProfileDataItem item;
			item.SetCate(strCateName);
			for (attr = eleItem->FirstAttribute();attr != NULL;attr = attr->Next()){
				if (strcmp(attr->Name(), "name") == 0){
					item.SetName(attr->Value());
				}
				if (strcmp(attr->Name(), "desc") == 0){
					item.SetDesc(attr->Value());
				}
				if (eleItem->FirstChild() != NULL){
					item.SetValue(eleItem->FirstChild()->Value());
				}
			}
			AddItem(item);
		}
	}
	return 0;
}

int XJXMLProfile::WriteFile(const string &strFilePath){
	int nRet = 0;
	m_strLastError.clear();
	//创建一个XML的文档对象。
	TiXmlDocument *pDocument = new TiXmlDocument();
	TiXmlDeclaration * pDecl = new TiXmlDeclaration( "1.0", "GB2312", "no");
	pDocument->LinkEndChild(pDecl);
	//创建一个根元素并连接。
	TiXmlElement *pRootElement = new TiXmlElement("configures");

	pDocument->LinkEndChild(pRootElement);
	unsigned i,j;
	string strCateName;
	vector<string > veCateNames;
	for (i=0;i<m_veDataItems.size();i++){
		XJXMLProfileDataItem &item = m_veDataItems[i];
		strCateName = item.GetCate();
		for (j=0;j<veCateNames.size();j++){
			if (veCateNames[j].compare(item.GetCate()) == 0){
				break;
			}
		}
		if (j == veCateNames.size()){
			veCateNames.push_back(strCateName);
		}else{
			continue;
		}
		TiXmlElement *eleCate = new TiXmlElement("cate");
		eleCate->SetAttribute("name", strCateName.c_str());
		pRootElement->LinkEndChild(eleCate);
		for (j=0;j<m_veDataItems.size();j++){
			XJXMLProfileDataItem &item2 = m_veDataItems[j];
			if (item2.GetCate().compare(item.GetCate()) == 0){
				TiXmlElement *eleItem = new TiXmlElement("item");
				eleItem->SetAttribute("name", item2.GetName().c_str());
				eleItem->SetAttribute("desc", item2.GetDesc().c_str());
				TiXmlText *pTextValue = new TiXmlText(item2.m_strValue.c_str());
				eleItem->LinkEndChild(pTextValue);
				eleCate->LinkEndChild(eleItem);
			}
		}
	}
	if (pDocument->SaveFile(strFilePath.c_str())){
		//
	}else{
		nRet = -1;
		m_strLastError = "SaveFile file error.";
		m_strLastError += strFilePath;
		m_strLastError += pDocument->ErrorDesc();
	}
	delete pDocument;
	pDocument = NULL;
	return nRet;
}

string &XJXMLProfile::GetLastError(){
	return m_strLastError;
}
void XJXMLProfile::Clear(){
	m_veDataItems.clear();
}
} /* namespace XJClassUtil */
